﻿#pragma once

#include <QObject>
#include <QVariantMap>
#include <QPointF>
#include <QColor>
#include <QTime>
#include <QDebug>
#include <cmath>
#include <QQmlApplicationEngine>

#include "customChartCurveInfoObject.h"
#include "CustomFunction.h"

extern QQmlApplicationEngine* gQmlEngine;

class CustomChart : public QObject{
    Q_OBJECT

public:

    // 曲线类型
    enum enCurveType{
        SCATTER = 0,
        LINE = 1,
        SPLINE = 2,
    };
    Q_ENUM(enCurveType);

    // 曲线点类型
    enum enScatterType{
        CIRCLE = 0,         // 散点图-圆
        RECTANGLE = 1,      // 散点图-正方形
        TRIANGLE = 2,       // 散点图-三角
        DOTTED = 3,         // 曲线/折线图-虚线(一块放在这儿了)
        RING = 4            // 散点图-空心圆
    };
    Q_ENUM(enScatterType);

    // 网格线类别
    enum enMeshTickType{
        AUTO = 0,                   // 自动调节（尽量取整数?我也忘了我原来咋算的了）
        FIXED_SPACE = 1,            // 固定间距
        FIXED_NUM = 2               // 固定数量（这里的数量指的是空白网格区域的数量，对应应该画num-1条线）
    };
    Q_ENUM(enMeshTickType);

    // x轴还是y轴还是一起设
    enum enTargetAxis{
        AXIS_X = 0,
        AXIS_Y = 1,
        AXIS_ALL = 2
    };
    Q_ENUM(enTargetAxis)

    struct stCurve{

        QVector<QPointF>    pointList;              // 原始曲线点
        QVector<QPointF>    normPointList;          // 归一化后的曲线点
        QVector<QPointF>    bezierPointList;        // 归一化后的贝塞尔点

        QVector<QPointF>    normPointList_full;          // 归一化后的曲线点
        QVector<QPointF>    bezierPointList_full;        // 归一化后的贝塞尔点


        enCurveType     curveType;
        enScatterType   scatterType = CIRCLE;       // 在curveType=SCATTER时生效
        int             lineWidth;
        QColor          color;
        qreal           minX;
        qreal           minY;
        qreal           maxX;
        qreal           maxY;

    };

    CustomChart();
    ~CustomChart();

    // QML接口
    Q_INVOKABLE CustomChartCurveInfoObject*  getCurveInfo();
    Q_INVOKABLE CustomChartCurveInfoObject*  getCurveInfo_fullImage();

    void appendCurve(QString name, QVector<QPointF> pointList, QColor color, int lineWidth, enCurveType type=LINE, enScatterType scType=CIRCLE);
    void clearFixedRange();
    void setFixedMinX(double value);
    void setFixedMinY(double value);
    void setFixedMaxX(double value);
    void setFixedMaxY(double value);

    Q_INVOKABLE void setShowRange(double x1, double x2, double y1, double y2);
    Q_INVOKABLE void setShowRangeX(double x1, double x2);
    Q_INVOKABLE void setShowRangeY(double y1, double y2);
    Q_INVOKABLE QVector<double> getShowRange();

    // 用于鼠标交互寻找相近的点
//    Q_INVOKABLE QPointF findPointInScope_byTruePosition(double x, double y, double radius);     // 根据真实坐标计算
    Q_INVOKABLE QPointF findPointInScope_byScalePosition(double dx, double dy, double dRadius = 0.05);    // 根据在图中的位置计算（考虑到缩放之后的）

    // 网格线类型配置
    Q_INVOKABLE bool setMeshTick(enTargetAxis axis, enMeshTickType type, double value = 0);       // type=auto时value不用填，其它情况下value<=0会报错


    Q_INVOKABLE void clear();
    Q_INVOKABLE void refresh();         // 重新计算坐标轴范围、归一化、贝塞尔曲线，并通知前端数据可更新

    Q_INVOKABLE void initShowRange();

    Q_INVOKABLE QString getLastError();     // 报错机制

    void printCurveInfo();

signals:
    void sigRefresh();          // 通知前端图表有新数据需要刷新
    void sigResetRange();       // 通知前端图表重置图表范围


private:

    // 参数计算
    void    calculate();
    void    calRange();
    void    calNorm();
    void    calBezier();
    void    calMesh();


    // 方法
    static double    calCeilRange(double value);     // 坐标轴的最大值向上取整

    // 绘制网格线



    CustomChartCurveInfoObject*  _infoObject = nullptr;

    QMap<QString, stCurve>   _curveList;

    // x/y的范围的默认最大值最小值
    qreal   _defaultMaxX = 1;
    qreal   _defaultMinX = 0;
    qreal   _defaultMaxY = 1;
    qreal   _defaultMinY = 0;

    bool    _isFixedMinX = false;
    bool    _isFixedMinY = false;
    bool    _isFixedMaxX = false;
    bool    _isFixedMaxY = false;


    qreal   _fixedMinX = 1;
    qreal   _fixedMinY = 1;
    qreal   _fixedMaxX = 2;
    qreal   _fixedMaxY = 2;

    // 每次执行calculate后都会重新算一遍范围
    qreal   _maxX;
    qreal   _minX;
    qreal   _minY;
    qreal   _maxY;

    // 缩放100%下的范围
    qreal   _fullMaxX;
    qreal   _fullMaxY;
    qreal   _fullMinX;
    qreal   _fullMinY;

    // 在min/max X/Y的基础上，调整绘制范围
    qreal   _showRangeX1 = 0;
    qreal   _showRangeX2 = 1;
    qreal   _showRangeY1 = 0;
    qreal   _showRangeY2 = 1;

    // 网格线类型
    enMeshTickType  _meshTickTypeX = FIXED_SPACE;
    enMeshTickType  _meshTickTypeY = AUTO;
    int             _meshNumX = 10;
    int             _meshNumY = 10;
    int             _meshSpaceX = 60;
    int             _meshSpaceY = 60;

    // 计算出来的网格线结果（坐标轴标注）
    QVector<double>                 _tickPercentX;
    QVector<double>                 _tickValueX;
    QVector<double>                 _tickPercentY;
    QVector<double>                 _tickValueY;
    // 缩放100%下的范围
    QVector<double>                 _fullTickPercentX;
    QVector<double>                 _fullTickValueX;
    QVector<double>                 _fullTickPercentY;
    QVector<double>                 _fullTickValueY;

    // 报错机制
    QString     _lastError = "NoErrorInfo";



};
